home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- * Basic Black ©1994 by Mason L. Bliss
- * - version 1.3.1 - 1/30/1994 -
- *
- * The trap patching code is taken from a neat little program
- * Mike Scanlin wrote for the August '92 MacTutor.
- *
- * Basic Black's screen-blanking routine was inspired by code written
- * by Christopher Tate.
- *
- * Basic Black makes use of CShowProc, by Ken McLeod, to show its
- * icon animation at startup time.
- *
- * Basic Black would be nowhere near as nice as it is without the
- * consistent help of my beta testers, who are listed in the Basic Black
- * read-me file. Thank you! ;-)
- *
- *********************************************************************/
-
- /*********************************************************************
- * Version History: (INIT code)
- *
- * 1.3.1 1/94
- * Fixed the 'SAVC' selector so that it now follows the After Dark
- * model. I had made an incorrect assumption about how it was supposed
- * to work.
- *
- * 1.3 1/94
- * Added support for After Dark's 'SAVR' gestalt selector, and added a
- * 'BBlk' gestalt selector to tell the cdev where our patch globals are.
- * Added support for AD's 'SAVC' screen saver control selector. Fixed
- * the problem where some windows' boundaries would be upset on occasion.
- * We now patch InitCursor and a couple other routines so that they don't
- * do anything while we're asleep.
- *
- * 1.2 6/93
- * Added an extra second to the lastAction patch global so as to avoid
- * problems with having the screen wake up and go back to sleep
- * immediately. Added optional bouncing clock. Added the ability to turn
- * Basic Black off via the cdev. Cleaned code.
- *
- * 1.1 4/93
- * Added user-configurability via ResEdit. Fixed support for multiple
- * monitors, and fixed problem with moving Desktop icons while in the
- * Finder.
- *
- * 1.0 2/93
- * First public release. Included an unfortunate number of bugs. :/
- *
- *********************************************************************/
-
-
-
- #include <Traps.h>
- #include <GestaltEqu.h>
- #include <ShutDown.h>
- #include "BB.h"
- #include "BBinit.h"
-
-
-
- /*********************************************************************
- * main:
- *
- * Gets memory in the system heap, installs our patches, and initializes
- * our patch globals. This is the only routine that gets executed at
- * startup time (by the INIT mechanism).
- *
- * Note that the code resource should be purgeable. The routines listed
- * below aren't used - the code, after it's loaded, is COPIED into the
- * area we set up in the system heap, after which the originals are
- * discarded, as it's the COPIES that are used. If the code resource is
- * set to "Not Purgeable" then the originals - which are never again
- * referenced - stick around until shutdown time, wasting memory.
- *
- * Also, with Think C, make sure that "Custom Headers" is turned on.
- *
- * The block of memory that we allocate will look like this when main()
- * has finished:
- *
- * +--------------------+
- * | PatchGlobals |
- * +--------------------+
- * | StartPatchCode() |
- * WNE trap addr -> +--------------------+
- * | MyWaitNextEvent() |
- * GNE trap addr -> +--------------------+
- * | MyGetNextEvent() |
- * IC trap addr -> +--------------------+
- * | MyInitCursor() |
- * DMB trap addr -> +--------------------+
- * | MyDrawMenuBar() |
- * ER trap addr -> +--------------------+
- * | MyEraseRect() |
- * EO trap addr -> +--------------------+
- * | MyEraseOval() |
- * EG trap addr -> +--------------------+
- * | MyEraseRgn() |
- * ST trap addr -> +--------------------+
- * | MySystemTask() |
- * +--------------------+
- * | BBlkSelector() |
- * +--------------------+
- * | SAVRSelector() |
- * +--------------------+
- * | SAVCSelector() |
- * +--------------------+
- * | SaverControl() |
- * +--------------------+
- * | FallAsleep() |
- * +--------------------+
- * | WakeUp() |
- * +--------------------+
- * | abs() |
- * +--------------------+
- * | DrawClock() |
- * +--------------------+
- * | RemoveICPatch() |
- * +--------------------+
- * | EndPatchCode() |
- * +--------------------+
- *
- *********************************************************************/
- void main()
- {
- Ptr patchPtr;
- PatchGlobalsPtr pgPtr;
- long codeSize, offset, oldA5;
- short icon;
- QDGlobals qd;
- GrafPort gp;
- Handle HConfig, procH;
- OSErr theError;
- Boolean drawStartupIcon = false;
-
- /* try and get some memory in the system heap for code and globals */
- codeSize = (long) EndPatchCode - (long) StartPatchCode;
- patchPtr = NewPtrSys(codeSize + sizeof(PatchGlobals));
- if (!patchPtr) {
- /* put up the error icon */
- if ((procH = GetIndResource('PROC', 1)) != 0L) {
- HLock(procH);
- CallPascal(128, -1, *procH);
- HUnlock(procH);
- }
- return; /* out of memory -- abort patching */
- }
-
- /* initialize the patch globals at the beginning of the block */
- pgPtr = (PatchGlobalsPtr) patchPtr;
- pgPtr->pgOldSTA = (STAProcPtr) GetTrapAddress(_SetTrapAddress);
- pgPtr->pgOldGTA = (GTAProcPtr) GetTrapAddress(_GetTrapAddress);
- pgPtr->pgOldWNE = (WNEProcPtr) GetTrapAddress(_WaitNextEvent);
- pgPtr->pgOldGNE = (GNEProcPtr) GetTrapAddress(_GetNextEvent);
- pgPtr->pgOldIC = (ICProcPtr) GetTrapAddress(_InitCursor);
- pgPtr->pgOldDMB = (DMBProcPtr) GetTrapAddress(_DrawMenuBar);
- pgPtr->pgOldER = (ERProcPtr) GetTrapAddress(_EraseRect);
- pgPtr->pgOldEO = (EOProcPtr) GetTrapAddress(_EraseOval);
- pgPtr->pgOldEG = (EGProcPtr) GetTrapAddress(_EraseRgn);
- pgPtr->pgOldST = (STProcPtr) GetTrapAddress(_SystemTask);
-
- /* move the code into place after the globals */
- BlockMove(StartPatchCode, patchPtr + sizeof(PatchGlobals), codeSize);
-
- /* set the patches */
- patchPtr += sizeof(PatchGlobals);
- offset = (long) MyWaitNextEvent - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _WaitNextEvent);
- offset = (long) MyGetNextEvent - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _GetNextEvent);
- offset = (long) MyInitCursor - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _InitCursor);
- offset = (long) MyDrawMenuBar - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _DrawMenuBar);
- offset = (long) MyEraseRect - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _EraseRect);
- offset = (long) MyEraseOval - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _EraseOval);
- offset = (long) MyEraseRgn - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _EraseRgn);
- offset = (long) MySystemTask - (long) StartPatchCode;
- SetTrapAddress((long) patchPtr + offset, _SystemTask);
-
- /* install a new 'BBlk' gestalt selector */
- offset = (long) BBlkSelector - (long) StartPatchCode;
- NewGestalt('BBlk', (ProcPtr) ((long) patchPtr + offset));
-
- /* install a new 'SAVR' gestalt selector */
- offset = (long) SAVRSelector - (long) StartPatchCode;
- NewGestalt('SAVR', (ProcPtr) ((long) patchPtr + offset));
-
- /* install a new 'SAVC' gestalt selector */
- offset = (long) SAVCSelector - (long) StartPatchCode;
- NewGestalt('SAVC', (ProcPtr) ((long) patchPtr + offset));
-
- /* install shutdown procedure */
- offset = (long) RemoveICPatch - (long) StartPatchCode;
- ShutDwnInstall( (ShutDwnProcPtr) ((long) patchPtr + offset),
- sdRestartOrPower + sdOnDrivers);
-
- pgPtr->pgSaverOn = false;
- pgPtr->pgPatchesIn = false;
- pgPtr->pgMustSleep = false;
- pgPtr->pgInSleepRect = false;
- pgPtr->pgLastAction = Ticks;
- pgPtr->pgLastRefresh = Ticks;
-
-
- /* Read the configuration information from our 'PREF' resource. */
- HConfig = GetIndResource('PREF', 1); // get the first 'PREF'
- pgPtr->pgSleepRect = (short) **HConfig;
- pgPtr->pgWakeRect = (short) *(*HConfig + 1);
- pgPtr->pgIdleTicks = (long) ((short) *(*HConfig + 2)) * 3600;
- pgPtr->pgBouncingClock = (Boolean) *(*HConfig + 3);
- pgPtr->pgMustSave = (Boolean) *(*HConfig + 4);
- pgPtr->pgRefreshTime = ((short) *(*HConfig + 5)) * 60;
- if (((short) *(*HConfig + 6)) == 1)
- drawStartupIcon = true;
- if (((short) *(*HConfig + 7)) == 0) { // Fade to black
- StuffHex(&(pgPtr->pgForePat), "\p0000000000000000");
- StuffHex(&(pgPtr->pgBackPat), "\pFFFFFFFFFFFFFFFF");
- } else { // Fade to white
- StuffHex(&(pgPtr->pgForePat), "\pFFFFFFFFFFFFFFFF");
- StuffHex(&(pgPtr->pgBackPat), "\p0000000000000000");
- }
- pgPtr->pgMenubarKluge = (Boolean) *(*HConfig + 8);
- ReleaseResource(HConfig);
-
-
- /* Read in the clock background picture. */
- pgPtr->pgClockBg = (PicHandle) GetResource('PICT', 255);
- DetachResource(pgPtr->pgClockBg);
-
-
- /* The next three lines fake out some QuickDraw globals so we can
- figure out the correct sleep and wake rectangles, as we don't
- have access to the 'proper' QuickDraw globals. */
- oldA5 = SetA5((long) &qd.qdend); // Point A5 at our fake globals
- InitGraf(&qd.thePort); // ...and initialize 'em
- OpenPort((GrafPtr) &gp);
-
- pgPtr->pgCorners[0].left = (gp.portRect).left - 1; // top left
- pgPtr->pgCorners[0].right = (gp.portRect).left + 8;
- pgPtr->pgCorners[0].top = (gp.portRect).top - 1;
- pgPtr->pgCorners[0].bottom = (gp.portRect).top + 8;
-
- pgPtr->pgCorners[1].left = (gp.portRect).right - 8; // top right
- pgPtr->pgCorners[1].right = (gp.portRect).right + 1;
- pgPtr->pgCorners[1].top = (gp.portRect).top - 1;
- pgPtr->pgCorners[1].bottom = (gp.portRect).top + 8;
-
- pgPtr->pgCorners[2].left = (gp.portRect).right - 8; // bottom right
- pgPtr->pgCorners[2].right = (gp.portRect).right + 1;
- pgPtr->pgCorners[2].top = (gp.portRect).bottom - 8;
- pgPtr->pgCorners[2].bottom = (gp.portRect).bottom + 1;
-
- pgPtr->pgCorners[3].left = (gp.portRect).left - 1; // bottom left
- pgPtr->pgCorners[3].right = (gp.portRect).left + 8;
- pgPtr->pgCorners[3].top = (gp.portRect).bottom - 8;
- pgPtr->pgCorners[3].bottom = (gp.portRect).bottom + 1;
-
- ClosePort((GrafPtr) &gp);
- oldA5 = SetA5(oldA5); // Restore A5 to its previous value
-
-
- /* put up our icon animation because the nice user wants us to */
- if (drawStartupIcon && (procH = GetIndResource('PROC', 1)) != 0L) {
- HLock(procH);
- /* display our cool little animation */
- for (icon = 128; icon < 133; ++icon) {
- offset = TickCount() + 5;
- CallPascal(icon, 0, *procH);
- while (offset > TickCount());
- }
- /* put up either the final icon, or the 'off' icon, as appropriate */
- if (pgPtr->pgMustSave)
- CallPascal(-4064, -1, *procH);
- else
- CallPascal(257, -1, *procH);
- HUnlock(procH);
- }
- }
-
-
-
- /*********************************************************************
- * StartPatchCode:
- *
- * Dummy proc to mark the beginning of the code for the
- * patches. Make sure all of your patch code is between
- * here and EndPatchCode.
- *
- *********************************************************************/
- void StartPatchCode()
- {
- }
-
-
-
- /*********************************************************************
- * MyWaitNextEvent:
- *
- * Tail patch on WaitNextEvent.
- *
- * The reason this returns a short instead of a Boolean is because we
- * need to make sure the low byte of the top word on the stack is zero
- * because some programs do a Tst.W (SP)+ when this returns instead of
- * Tst.B (SP)+ like they should (which is technically their bug but, we
- * might as well work around it since it's not hard).
- *
- * If you want to eat the event (not pass it on to the caller) then set
- * returnValue to zero.
- *
- *********************************************************************/
- pascal short MyWaitNextEvent(short eventMask, EventRecord *theEvent, long sleep, RgnHandle mouseRgn)
- {
- PatchGlobalsPtr pgPtr;
- short returnValue;
- register short foo;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original GNE first */
- returnValue = (*pgPtr->pgOldWNE) (eventMask, theEvent, sleep, mouseRgn);
-
- if ((foo = theEvent->what) >= 1 && foo <= 5 || foo == 7) {
- pgPtr->pgLastAction = Ticks; /* Update last time counter */
- pgPtr->pgInSleepRect = false;
- if (pgPtr->pgSaverOn) {
- foo = theEvent->what;
- if (foo >= 3 && foo <= 5) { /* mask keypresses and clicks */
- returnValue = 0;
- theEvent->what = nullEvent;
- }
- WakeUp();
- }
- }
-
- /* return to original caller */
- return returnValue;
- }
-
-
-
- /*********************************************************************
- * MyGetNextEvent:
- *
- * Tail patch on GetNextEvent.
- *
- * The reason this returns a short instead of a Boolean is because we
- * need to make sure the low byte of the top word on the stack is zero
- * because some programs do a Tst.W (SP)+ when this returns instead of
- * Tst.B (SP)+ like they should (which is technically their bug but, we
- * might as well work around it since it's not hard).
- *
- * If you want to eat the event (not pass it on to the caller) then set
- * returnValue to zero.
- *
- *********************************************************************/
- pascal short MyGetNextEvent(short eventMask, EventRecord *theEvent)
- {
- PatchGlobalsPtr pgPtr;
- short returnValue;
- register short foo;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original GNE first */
- returnValue = (*pgPtr->pgOldGNE) (eventMask, theEvent);
-
- if ((foo = theEvent->what) >= 1 && foo <= 5 || foo == 7) {
- pgPtr->pgLastAction = Ticks; /* Update last time counter */
- pgPtr->pgInSleepRect = false;
- if (pgPtr->pgSaverOn) {
- foo = theEvent->what;
- if (foo >= 3 && foo <= 5) { /* mask keypresses and clicks */
- returnValue = 0;
- theEvent->what = nullEvent;
- }
- WakeUp();
- }
- }
-
- /* return to original caller */
- return returnValue;
- }
-
-
-
- /*********************************************************************
- * MyInitCursor:
- *
- * Patch that disables InitCursor if we're asleep.
- *
- *********************************************************************/
- pascal void MyInitCursor()
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original IC first */
- if (pgPtr->pgSaverOn == false)
- (*pgPtr->pgOldIC) ();
- }
-
-
-
- /*********************************************************************
- * MyDrawMenuBar:
- *
- * Patch that disables DrawMenuBar if we're asleep.
- *
- *********************************************************************/
- pascal void MyDrawMenuBar()
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original DMB first */
- if (pgPtr->pgSaverOn == false)
- (*pgPtr->pgOldDMB) ();
- }
-
-
-
- /*********************************************************************
- * MyEraseRect:
- *
- * Patch that disables EraseRect if we're asleep.
- *
- *********************************************************************/
- pascal void MyEraseRect(Rect *rect)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original ER first */
- if (pgPtr->pgSaverOn == false)
- (*pgPtr->pgOldER) (rect);
- }
-
-
-
- /*********************************************************************
- * MyEraseOval:
- *
- * Patch that disables EraseOval if we're asleep.
- *
- *********************************************************************/
- pascal void MyEraseOval(Rect *rect)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original EO first */
- if (pgPtr->pgSaverOn == false)
- (*pgPtr->pgOldEO) (rect);
- }
-
-
-
- /*********************************************************************
- * MyEraseRgn:
- *
- * Patch that disables EraseRgn if we're asleep.
- *
- *********************************************************************/
- pascal void MyEraseRgn(RgnHandle rgn)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* call original EG first */
- if (pgPtr->pgSaverOn == false)
- (*pgPtr->pgOldEG) (rgn);
- }
-
-
-
- /*********************************************************************
- * MySystemTask:
- *
- * Patches SystemTask. This is where most of our maintenance is done.
- *
- *********************************************************************/
- pascal void MySystemTask(void)
- {
- PatchGlobalsPtr pgPtr;
- Point mousePt;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* Check to see if the mouse has moved */
- GetMouse(&mousePt);
- LocalToGlobal(&mousePt);
- if (!EqualPt(mousePt, pgPtr->pgLastMouse)) { /* id est, mouse moved */
- pgPtr->pgLastMouse = mousePt;
- if (pgPtr->pgSaverOn)
- WakeUp();
- else {
- pgPtr->pgLastAction = Ticks;
- pgPtr->pgInSleepRect = false;
- }
- }
-
- /* Does the nice user want us to fall asleep now? */
- if (!(pgPtr->pgInSleepRect) && PtInRect(mousePt, &pgPtr->pgCorners[pgPtr->pgSleepRect])) {
- pgPtr->pgInSleepRect = true;
- /* Set the clocks back so it looks like we haven't moved for a while. */
- pgPtr->pgLastAction -= ((pgPtr->pgIdleTicks) - DELAYTICKS);
- }
-
- /* Is the mouse in the Never Sleep corner? */
- if (PtInRect(mousePt, &pgPtr->pgCorners[pgPtr->pgWakeRect]))
- pgPtr->pgLastAction = Ticks;
-
- /* Has enough idle time passed for us to fall asleep naturally? */
- if (((Ticks - (pgPtr->pgLastAction)) > (pgPtr->pgIdleTicks))
- && !(pgPtr->pgSaverOn))
- pgPtr->pgMustSleep = true;
-
- /* Do sleepy-time maintenance. */
- if (pgPtr->pgSaverOn) {
- /* Take care of the refresh timing */
- if ((Ticks - pgPtr->pgLastRefresh) > pgPtr->pgRefreshTime) {
- pgPtr->pgLastRefresh = Ticks;
- pgPtr->pgMustSleep = true;
- }
-
- /* Has the menu been messed with? (Don't mess with me, man!) */
- /* Canvas users truly hate this. It's Aldus' fault - not mine. */
- if (pgPtr->pgMenubarKluge && MBarHeight != 0)
- pgPtr->pgMustSleep = true;
- }
-
- /* Do we need to fall asleep? */
- if (pgPtr->pgMustSleep && pgPtr->pgMustSave)
- FallAsleep();
-
- /* Now give everyone else some time! */
- (*pgPtr->pgOldST) ();
- }
-
-
-
- /*********************************************************************
- * BBlkSelector:
- *
- * 'BBlk' gestalt selector that provides the address of our patch
- * globals. This is *much* cleaner than patching SizeResource().
- *
- *********************************************************************/
- pascal void BBlkSelector(OSType selector, long *result)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- /* ...and give 'em back! */
- *result = (long) pgPtr;
- }
-
-
-
- /*********************************************************************
- * SAVRSelector:
- *
- * 'SAVR' gestalt selector that tells the world when we're alive and
- * also when we're sleeping.
- *
- *********************************************************************/
- pascal void SAVRSelector(OSType selector, long *result)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- *result = 0;
-
- /* if we haven't been disabled, tell the world of our presence */
- if (pgPtr->pgMustSave == true)
- *result |= 1; // saver enabled
-
- /* If screen is black, tell the world we're alive */
- if (pgPtr->pgSaverOn == true) {
- *result |= 2; // saver asleep
- *result |= 16; // app drawing disabled
- }
- }
-
-
-
- /*********************************************************************
- * SAVCSelector:
- *
- * The 'SAVC' gestalt selector passes back the address of our control
- * routine so that other applications can control us.
- *
- * We can be turned on and off remotely, and we can be told to put
- * the screen to sleep and wake the screen up. Neat, huh?
- *
- *********************************************************************/
- pascal void SAVCSelector(OSType selector, long *result)
- {
- *result = (long) SaverControl;
- }
-
-
-
- /*********************************************************************
- * SaverControl:
- *
- * Executes a command from an application.
- *
- *********************************************************************/
- pascal OSErr SaverControl(short theCommand)
- {
- PatchGlobalsPtr pgPtr;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- switch (theCommand) {
- case eSaverWakeUp: // Make Basic Black wake up.
- if (pgPtr->pgSaverOn)
- WakeUp();
- break;
-
- case eSaverSleep: // Make Basic Black go to sleep.
- pgPtr->pgMustSleep = true;
- break;
-
- case eSaverOn: // Turn Basic Black on.
- pgPtr->pgMustSave = true;
- pgPtr->pgMustSleep = false;
- break;
-
- case eSaverOff: // Turn Basic Black off.
- pgPtr->pgMustSave = false;
- break;
- }
-
- return noErr;
- }
-
-
-
- /*********************************************************************
- * FallAsleep:
- *
- * This is where we black out the screen.
- *
- *********************************************************************/
- void FallAsleep(void)
- {
- PatchGlobalsPtr pgPtr;
- GrafPort myPort;
- GrafPtr oldPort;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- pgPtr->pgSaverOn = true;
- pgPtr->pgMustSleep = false;
- pgPtr->pgLastRefresh = Ticks;
-
- /* hide the cursor */
- ObscureCursor();
-
- /* Fix the menu bar if the kluge is on and the MBarHeight's been changed */
- if (pgPtr->pgMenubarKluge && MBarHeight != 0) {
- pgPtr->pgOldHeight = MBarHeight;
- MBarHeight = 0;
- }
-
- /* Save the old port and set our new characteristics */
- GetPort(&oldPort);
- OpenPort(&myPort);
- PenPat(pgPtr->pgForePat);
- BackPat(pgPtr->pgBackPat);
-
- /* Get a region for everything, and paint it. */
- UnionRgn(GrayRgn, myPort.visRgn, myPort.visRgn);
- FillRgn(myPort.visRgn, pgPtr->pgBackPat);
-
- /* Draw our clock, if it's turned on. */
- if (pgPtr->pgBouncingClock)
- DrawClock(&myPort);
-
- /* Empty the visRgns of all windows */
- CopyRgn(GrayRgn, myPort.visRgn);
- SetEmptyRgn(GrayRgn);
- CalcVisBehind((WindowPeek) FrontWindow(), myPort.visRgn);
- CopyRgn(myPort.visRgn, GrayRgn);
-
- /* Restore the old port */
- ClosePort(&myPort);
- SetPort(oldPort);
- }
-
-
-
- /*********************************************************************
- * WakeUp:
- *
- * This is where we liven up.
- *
- *********************************************************************/
- void WakeUp(void)
- {
- PatchGlobalsPtr pgPtr;
- GrafPtr oldPort;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- pgPtr->pgSaverOn = false;
- pgPtr->pgInSleepRect = false;
- pgPtr->pgLastAction = Ticks + 60; /* can't sleep for a second */
-
- /* restore the menu bar */
- if (pgPtr->pgMenubarKluge)
- MBarHeight = pgPtr->pgOldHeight;
- DrawMenuBar();
-
- /* Grab the current port. */
- GetPort(&oldPort);
-
- /* Redraw window frames and set update regions equal to visible regions */
- PaintBehind((WindowPeek) FrontWindow(), GrayRgn);
-
- /* Calculate visRgns */
- CalcVisBehind((WindowPeek) FrontWindow(), GrayRgn);
-
- /* Reset the port - the previous two toolbox calls disrupt it. */
- SetPort(oldPort);
- }
-
-
-
- /*********************************************************************
- * abs:
- *
- * Return the absolute value of a short.
- *
- *********************************************************************/
- short abs(short x)
- {
- return x < 0 ? -x : x;
- }
-
-
-
- /*********************************************************************
- * DrawClock:
- *
- * Draw an analog clock at a random place in the given
- * GrafPort.
- *
- *********************************************************************/
- void DrawClock(GrafPtr myPort)
- {
- PatchGlobalsPtr pgPtr;
- DateTimeRec theTime;
- Rect theTimeRect;
- short mid;
-
- /* find our globals */
- pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
-
- GetTime(&theTime);
-
- /* find our clock rectangle */
- theTimeRect.top = (abs(Random()) % (myPort->portRect.bottom - 110)) + 5;
- theTimeRect.bottom = theTimeRect.top + 100;
- theTimeRect.left = (abs(Random()) % (myPort->portRect.right - 110)) + 5;
- theTimeRect.right = theTimeRect.left + 100;
-
- /* draw our background */
- DrawPicture(pgPtr->pgClockBg, &theTimeRect);
-
- /* move the rect in, and draw the minute hand */
- InsetRect(&theTimeRect, 5, 5);
- PaintArc(&theTimeRect, (theTime.minute) * 6 - 3, 6);
-
- /* move the rect in more, and draw the hour hand */
- InsetRect(&theTimeRect, 15, 15);
- PaintArc(&theTimeRect, (theTime.hour % 12) * 30 - 5 + (theTime.minute / 2), 10);
- }
-
-
-
- /*********************************************************************
- * RemoveICPatch:
- *
- * Shutdown procedure that replaces the InitCursor patch.
- *
- * This is an unspeakably evil way to do this, but since our patch
- * globals are destroyed before shutdown, leading to our InitCursor
- * routine gagging and dying horribly when called, there isn't any
- * better way to do this that I know of. Blame Apple for not preserving
- * memory to the end.
- *
- * Anyways, yes, this *is* what it looks like. For shutdown purposes,
- * we're replacing InitCursor with ShowCursor... :/
- *
- *********************************************************************/
- pascal void RemoveICPatch()
- {
- SetTrapAddress(GetTrapAddress(_ShowCursor), _InitCursor);
- }
-
-
-
- /*********************************************************************
- * EndPatchCode:
- *
- * Dummy proc to mark the end of the code for the patches.
- * Make sure all of your patch code is between here and
- * StartPatchCode.
- *
- *********************************************************************/
- void EndPatchCode()
- {
- }
-